package org.bedracket.pgeg.event;

import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.item.enchantment.EnchantmentInstance;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.event.AttachCapabilitiesEvent;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.event.entity.EntityJoinLevelEvent;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.network.PacketDistributor;
import org.bedracket.pgeg.PGEGMod;
import org.bedracket.pgeg.capability.ManaLevelCapabilityProvider;
import org.bedracket.pgeg.init.ModCapabilities;
import org.bedracket.pgeg.init.ModTags;
import org.bedracket.pgeg.network.PlayerManaMessage;
import org.bedracket.pgeg.network.SimpleNetworkHandler;
import org.bedracket.pgeg.util.Helpers;

import java.util.List;

@Mod.EventBusSubscriber(modid = PGEGMod.MOD_ID)
public class PlayerEvents {

    @SubscribeEvent
    public static void addCap(AttachCapabilitiesEvent<Entity> event) {
        if (event.getObject() instanceof Player && !(event.getObject() instanceof FakePlayer)) {
            event.addCapability(Helpers.identifier("player_mana_level"),
                    new ManaLevelCapabilityProvider());
        }
    }

    @SubscribeEvent
    public static void onPlayerJoinLevel(EntityJoinLevelEvent event) {
        var entity = event.getEntity();
        if (entity instanceof final Player player
                && ! (entity instanceof FakePlayer)) {
            if (player instanceof final ServerPlayer serverPlayer) {
                serverPlayer.getCapability(ModCapabilities.PLAYER_MANA_LEVEL).ifPresent(capability -> {
                    capability.setManaLevel((float) capability.getMaxManaLevel());
                    SimpleNetworkHandler.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() ->
                                    serverPlayer),
                            new PlayerManaMessage((float) capability.getMaxManaLevel(), capability.getMaxManaLevel()));
                });
            }
        }
    }

    @SubscribeEvent
    public static void onPlayerTick(TickEvent.PlayerTickEvent event) {
        var player = event.player;
        if (!(player instanceof FakePlayer) && player instanceof final ServerPlayer serverPlayer) {
            serverPlayer.getCapability(ModCapabilities.PLAYER_MANA_LEVEL)
                    .ifPresent(capability -> {
                        if (capability.getManaLevel() < capability.getMaxManaLevel()
                                && serverPlayer.tickCount % 20 == 0) {
                            capability.regenManaLevel(0.05f);
                            SimpleNetworkHandler.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() ->
                                            serverPlayer),
                                    new PlayerManaMessage(capability.getManaLevel(), capability.getMaxManaLevel()));
                        }
                    });
        }
    }

    @SubscribeEvent
    public static void onPlayerLoggedInEvent(PlayerEvent.PlayerLoggedInEvent event) {
        if (event.getEntity() instanceof ServerPlayer serverPlayer && !(event.getEntity() instanceof FakePlayer)) {
            serverPlayer.getCapability(ModCapabilities.PLAYER_MANA_LEVEL).ifPresent(t -> {
                t.setManaLevel((float) t.getMaxManaLevel());
                SimpleNetworkHandler.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() ->
                                serverPlayer),
                        new PlayerManaMessage(t.getManaLevel(), t.getMaxManaLevel()));
                    });
        }
    }

    @SubscribeEvent
    public static void onCrafted(PlayerEvent.ItemCraftedEvent event) {
        var stack = event.getCrafting();
        var player = event.getEntity();
        var level = player.getLevel();
        if (stack.is(ModTags.ModItemTags.SATURNIUM_TOOLS)) {
            List<EnchantmentInstance> enchantmentList =
                    EnchantmentHelper.selectEnchantment(level.random, stack, 20, true);
            enchantmentList.forEach(enchantmentInstance
                    -> stack.enchant(enchantmentInstance.enchantment, enchantmentInstance.level));
        }
    }
}
